all_hide_info = {
    '姤': {16: ('生', '长')}, '遁': {16: ('', '死'), 17: ('克', '墓')}, '否': {17: ('克', '养')},
    '观': {13: ('克', '长'), 17: ('克', '养')}, '剥': {13: ('', '死')}, '晋': {17: ('克', '养')},
    '豫': {17: ('克', '养')}, '解': {17: ('', '病')}, '恒': {16: ('生', '长')},
    '升': {14: ('', '养'), 16: ('生', '长')}, '井': {14: ('', '病'), 16: ('生', '长')},
    '大过': {14: ('克', '绝'), 16: ('生', '长')}, '随': {14: ('克', '绝')}, '屯': {15: ('', '冠')},
    '既济': {15: ('克', '绝')}, '革': {15: ('克', '绝')}, '明夷': {15: ('克', '绝')}, '小畜': {15: ('生', '养')},
    '家人': {15: ('', '病')}, '益': {15: ('生', '养')}, '颐': {13: ('克', '胎'), 15: ('生', '养')},
    '蛊': {13: ('克', '胎')}, '贲': {15: ('', '病'), 16: ('', '养')}, '大畜': {15: ('生', '养'), 16: ('生', '长')},
    '损': {15: ('生', '墓')}, '睽': {13: ('克', '养')}, '履': {13: ('生', '长')},
    '中孚': {13: ('', '绝'), 15: ('生', '墓')}, '渐': {13: ('', '绝')}, '复': {16: ('生', '长')},
    '泰': {16: ('生', '长')}, '夬': {16: ('生', '长')}, '需': {16: ('生', '长')},
    '旅': {15: ('生', '长'), 17: ('', '衰')}, '鼎': {17: ('', '冠')}, '未济': {15: ('', '胎')},
    '蒙': {14: ('生', '衰')}, '涣': {14: ('生', '冠'), 15: ('', '胎')}, '讼': {15: ('', '胎')},
    '咸': {16: ('', '死')}, '蹇': {16: ('', '死')}, '谦': {16: ('', '死')}, '小过': {14: ('', '胎'), 16: ('', '死')},
    '归妹': {14: ('', '胎')}
    # 使用方法：dic['姤'][16] = ('生', '长')
    # 提示：16 = 12 + 1~5（五爻到初爻）
    # puzzle:飞神生，飞神长生，飞神死地，飞神胎地
}

# 索引是'卦序'(gua_num);
# [六爻地支数，五爻，四爻，三爻，二爻，初爻];12 代表亥，di_zhi % 12 可以避免报错
GUA_SHU = [[11, 9, 7, 5, 3, 1], [11, 9, 7, 10, 12, 2], [11, 9, 7, 9, 7, 5], [11, 9, 7, 4, 6, 8], [4, 6, 8, 4, 6, 8],
           [3, 1, 11, 4, 6, 8], [6, 8, 10, 4, 6, 8], [6, 8, 10, 5, 3, 1], [11, 9, 7, 5, 3, 1], [11, 9, 7, 4, 6, 8],
           [11, 9, 7, 7, 5, 3], [11, 9, 7, 10, 12, 2], [10, 12, 2, 10, 12, 2], [1, 11, 9, 10, 12, 2],
           [8, 10, 12, 10, 12, 2],
           [8, 10, 12, 5, 3, 1], [1, 11, 9, 7, 5, 3], [1, 11, 9, 2, 4, 6], [1, 11, 9, 5, 3, 1], [1, 11, 9, 12, 2, 4],
           [8, 10, 12, 12, 2, 4], [11, 9, 7, 12, 2, 4], [10, 12, 2, 12, 2, 4], [10, 12, 2, 7, 5, 3],
           [4, 6, 8, 10, 12, 2],
           [4, 6, 8, 5, 3, 1], [4, 6, 8, 12, 2, 4], [4, 6, 8, 5, 3, 1], [11, 9, 7, 5, 3, 1], [6, 8, 10, 5, 3, 1],
           [3, 1, 11, 5, 3, 1], [3, 1, 11, 10, 12, 2], [3, 1, 11, 9, 7, 5], [3, 1, 11, 12, 2, 4], [3, 1, 11, 5, 3, 1],
           [3, 1, 11, 2, 4, 6], [6, 8, 10, 2, 4, 6], [11, 9, 7, 2, 4, 6], [4, 6, 8, 2, 4, 6], [4, 6, 8, 9, 7, 5],
           [10, 12, 2, 4, 6, 8], [10, 12, 2, 5, 3, 1], [10, 12, 2, 2, 4, 6], [10, 12, 2, 5, 3, 1], [11, 9, 7, 5, 3, 1],
           [8, 10, 12, 5, 3, 1], [1, 11, 9, 5, 3, 1], [1, 11, 9, 4, 6, 8], [6, 8, 10, 12, 2, 4], [6, 8, 10, 9, 7, 5],
           [6, 8, 10, 10, 12, 2], [6, 8, 10, 7, 5, 3], [3, 1, 11, 7, 5, 3], [4, 6, 8, 7, 5, 3], [11, 9, 7, 7, 5, 3],
           [11, 9, 7, 12, 2, 4], [8, 10, 12, 2, 4, 6], [8, 10, 12, 7, 5, 3], [8, 10, 12, 4, 6, 8], [8, 10, 12, 9, 7, 5],
           [1, 11, 9, 9, 7, 5], [10, 12, 2, 9, 7, 5], [11, 9, 7, 9, 7, 5], [11, 9, 7, 2, 4, 6]]

# [六爻伏藏的地支数，五爻，四爻，三爻，二爻，初爻];None 说明这个爻位没有伏藏，用于占位
HIDE_SHU = [[None, None, None, None, None, None], [None, None, None, None, 3, None],
            [None, None, None, None, 3, 1],
            [None, None, None, None, None, 1], [None, 9, None, None, None, 1], [None, 9, None, None, None, None],
            [None, None, None, None, None, 1], [None, None, None, None, None, None],
            [None, None, None, None, None, None],
            [None, None, None, None, None, 1], [None, None, None, None, None, 1],
            [None, None, None, None, 3, None],
            [None, None, 7, None, 3, None], [None, None, 7, None, 3, None], [None, None, 7, None, 3, None],
            [None, None, 7, None, None, None], [None, None, None, None, None, None],
            [None, None, None, None, None, None],
            [None, None, None, 7, None, None], [None, None, None, 7, None, None],
            [None, None, None, 7, None, None],
            [None, None, None, None, None, None], [None, None, None, 7, None, None],
            [None, None, None, None, None, None],
            [None, None, None, None, None, None], [None, None, None, 10, None, None],
            [None, None, None, 10, None, None],
            [None, None, None, 10, None, None], [None, None, None, None, None, None],
            [None, None, None, None, None, None],
            [None, 6, None, 10, None, None], [None, 6, None, None, None, None],
            [None, None, None, None, None, None],
            [None, None, None, 9, 7, None], [None, None, None, 9, 7, None], [None, None, None, 9, None, None],
            [None, 1, None, None, None, None], [None, 1, None, None, None, None], [None, 1, None, 9, None, None],
            [None, 1, None, None, None, None], [None, None, None, None, None, None],
            [None, None, None, None, 6, None],
            [None, None, None, None, None, None], [None, None, None, None, 6, None],
            [None, None, None, None, None, None],
            [None, None, None, None, 6, None], [None, None, None, None, 6, None],
            [None, None, None, None, None, None],
            [None, None, None, None, None, None], [None, None, None, 12, None, 4],
            [None, None, None, None, None, 4],
            [None, None, None, 12, None, None], [None, None, 10, None, None, None],
            [None, None, 10, 12, None, None],
            [None, None, None, 12, None, None], [None, None, None, None, None, None],
            [None, None, None, None, None, None],
            [None, None, None, None, None, None], [None, None, None, None, None, None],
            [None, None, None, None, 4, None],
            [None, None, None, None, 4, None], [None, None, None, None, 4, None],
            [None, None, 12, None, 4, None],
            [None, None, 12, None, None, None]]

# 给定卦序 gua_num ,获得卦宫五行数(也就是下文的 index)。
# 一个专门的map:REMINDER_TO_WU_XING，把 gua_num // 8 转化成 index)
# example:index = REMINDER_TO_WU_XING[gua_num // 8]
REMINDER_TO_WU_XING = [4, 3, 1, 3, 0, 0, 2, 4]
REMAINDER_TO_SIX_MODE = [0, 1, 1, 2, 2, 3, 4, 5, 5, 0]

# 储存的是 FAMILY的索引组，顺序是卦宫五行数(index)：
# index:0,卦宫属土，艮/坤；1,卦宫属水，坎；2,卦宫属火，离；3,卦宫属木，震/巽；4,卦宫属金，乾/兑；
# example:簇 = LIU_QIN_NUM_60[index]
LIU_QIN_NUM_60 = [[36, 37, 14, 51, 52, 17, 6, 7, 20, 33, 34, 23], [12, 13, 50, 27, 28, 53, 42, 43, 56, 9, 10, 59],
                  [48, 49, 26, 3, 4, 29, 18, 19, 32, 45, 46, 35], [0, 1, 38, 15, 16, 41, 30, 31, 44, 57, 58, 47],
                  [24, 25, 2, 39, 40, 5, 54, 55, 8, 21, 22, 11]]

# 卦宫的地支数(num % 12)，包含了“六亲”(num // 12)
# idx % 12 == 0:亥，idx % 12 == 1:子，
# idx // 12 == 1:brother,2:son,3:money,4:ghost
FAMILY = ['父母亥水', '父母子水', '父母丑土', '父母寅木', '父母卯木', '父母辰土', '父母巳火', '父母午火', '父母未土',
          '父母申金', '父母酉金', '父母戌土', '兄弟亥水', '兄弟子水', '兄弟丑土', '兄弟寅木', '兄弟卯木', '兄弟辰土',
          '兄弟巳火', '兄弟午火', '兄弟未土', '兄弟申金', '兄弟酉金', '兄弟戌土', '子孙亥水', '子孙子水', '子孙丑土',
          '子孙寅木', '子孙卯木', '子孙辰土', '子孙巳火', '子孙午火', '子孙未土', '子孙申金', '子孙酉金', '子孙戌土',
          '妻财亥水', '妻财子水', '妻财丑土', '妻财寅木', '妻财卯木', '妻财辰土', '妻财巳火', '妻财午火', '妻财未土',
          '妻财申金', '妻财酉金', '妻财戌土', '官鬼亥水', '官鬼子水', '官鬼丑土', '官鬼寅木', '官鬼卯木', '官鬼辰土',
          '官鬼巳火', '官鬼午火', '官鬼未土', '官鬼申金', '官鬼酉金', '官鬼戌土', '官鬼亥水']
GAN = ["癸", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬"]
ZHI = ["亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌"]
KONG_WANG = ["戌亥", "子丑", "寅卯", "辰巳", "午未", "申酉"]
YONG_SHEN = ["父母", '兄弟', '子孙', '妻财', '官鬼', '世', '应']
ANIMALS = ["青龙", "朱雀", "勾陈", "腾蛇", "白虎", "玄武"]
YAO_WEI = ["六", "五", "四", "三", "二", "初"]
KEY_SAYING = {"腾蛇": "性格行为古怪，孤僻。临元神为不安，被冲克更是。",
              "白虎": "性格暴躁，着急", "白虎水爻": "白虎水爻为血。",
              "青龙": "青龙主家务日常",
              "朱雀": "朱雀主口舌，发炎发烧。",
              "勾陈": "勾陈主懒惰，迟钝。用神临勾陈，不动之象。",
              "玄武": "玄武主郁闷压抑，心情不好，日月克尤甚。", }
GUA_INFO = [
    ['<五爻克宅>', '<五爻生宅>', '<宅爻克五>', '<宅爻克五>', '<五宅比和>', '<五爻克宅>', '<宅爻生五>', '<宅爻克五>',
     '<五爻克宅>',
     '<宅爻克五>', '<宅爻生五>', '<五爻生宅>', '<五宅比和>', '<五爻克宅>', '<五爻生宅>', '<五爻克宅>', '<五宅比和>',
     '<宅爻克五>',
     '<宅爻克五>', '<五宅比和>', '<宅爻生五>', '<宅爻生五>', '<宅爻克五>', '<宅爻克五>', '<宅爻克五>', '<宅爻生五>',
     '<五爻生宅>',
     '<宅爻生五>', '<五爻克宅>', '<宅爻克五>', '<五爻生宅>', '<五宅比和>', '<五爻克宅>', '<宅爻克五>', '<五爻生宅>',
     '<五爻生宅>',
     '<宅爻克五>', '<五爻克宅>', '<宅爻生五>', '<五宅比和>', '<五爻克宅>', '<五爻生宅>', '<五爻生宅>', '<五爻生宅>',
     '<五爻克宅>',
     '<五爻克宅>', '<宅爻克五>', '<宅爻生五>', '<五宅比和>', '<宅爻生五>', '<五爻克宅>', '<五宅比和>', '<宅爻克五>',
     '<五爻生宅>',
     '<宅爻生五>', '<宅爻生五>', '<五爻克宅>', '<宅爻生五>', '<宅爻克五>', '<宅爻克五>', '<宅爻生五>', '<五爻克宅>',
     '<宅爻克五>',
     '<五爻克宅>'],
    ['<世应比和>', '<应爻生世>', '<世爻克应>', '<世爻克应>', '<世应比和>', '<世爻克应>', '<应爻生世>', '<应爻生世>',
     '<世应比和>',
     '<应爻生世>', '<世爻生应>', '<应爻生世>', '<世应比和>', '<世爻克应>', '<应爻克世>', '<世应比和>', '<世爻克应>',
     '<世爻克应>',
     '<世爻克应>', '<世应比和>', '<世爻生应>', '<应爻生世>', '<应爻克世>', '<世爻克应>', '<应爻克世>', '<应爻克世>',
     '<应爻生世>',
     '<应爻克世>', '<应爻克世>', '<应爻克世>', '<世爻克应>', '<世爻克应>', '<应爻克世>', '<世爻克应>', '<应爻生世>',
     '<应爻克世>',
     '<应爻克世>', '<世爻克应>', '<应爻生世>', '<世爻克应>', '<世爻克应>', '<应爻克世>', '<应爻生世>', '<世爻生应>',
     '<应爻克世>',
     '<世爻克应>', '<世爻生应>', '<应爻生世>', '<应爻克世>', '<世爻生应>', '<应爻克世>', '<世应比和>', '<应爻克世>',
     '<世爻生应>',
     '<应爻生世>', '<应爻克世>', '<世应比和>', '<应爻生世>', '<世爻克应>', '<应爻生世>', '<应爻生世>', '<世爻克应>',
     '<世爻生应>',
     '<世应比和>'],
    ['<八卦纯阳>', '', '<八卦纯阳>', '', '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阳>', '', '<八卦纯阳>', '',
     '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阳>', '', '<八卦纯阳>', '', '<八卦纯阴>', '', '<八卦纯阴>', '',
     '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阳>', '', '<八卦纯阳>', '', '<八卦纯阳>', '', '<八卦纯阳>', '',
     '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阳>', '', '<八卦纯阳>', '',
     '<八卦纯阴>', '', '<八卦纯阴>', '', '<八卦纯阳>', '', '<八卦纯阳>', '', '<八卦纯阴>', '', '<八卦纯阴>', '',
     '<八卦纯阳>', '', '<八卦纯阳>', ''],
    ['', '', '', '', '', '', '', '<世应同宫>', '', '<世五同宫>', '', '<应二同宫>', '', '<世应同宫>', '', '', '', '', '',
     '<世五同宫>', '', '', '', '', '', '', '', '<世五同宫>', '', '', '', '<应初同宫>', '', '<应三同宫>', '',
     '<世应同宫>', '', '', '', '<世四同宫>', '', '<应二同宫>', '', '', '', '', '', '', '', '<世六同宫>', '',
     '<应二同宫>', '', '<世应同宫>', '', '<世应同宫>', '', '', '', '<世应同宫>', '', '', '', '']

]
GUA_NAME = [
    '乾', '姤', '遁', '否', '观', '剥', '晋', '大有', '震', '豫', '解', '恒', '升', '井', '大过', '随',
    '坎', '节', '屯', '既济', '革', '丰', '明夷', '师', '巽', '小畜', '家人', '益', '无妄', '噬嗑', '颐', '蛊',
    '艮', '贲', '大畜', '损', '睽', '履', '中孚', '渐', '坤', '复', '临', '泰', '大壮', '夬', '需', '比',
    '离', '旅', '鼎', '未济', '蒙', '涣', '讼', '同人', '兑', '困', '萃', '咸', '蹇', '谦', '小过', '归妹']
GUA_NAMES = [
    '乾为天', '天风姤', '天山遁', '天地否', '风地观', '山地剥', '火地晋', '火天大有', '震为雷', '雷地豫', '雷水解',
    '雷风恒', '地风升', '水风井', '泽风大过', '泽雷随', '坎为水', '水泽节', '水雷屯', '水火既济', '泽火革', '雷火丰',
    '地火明夷', '地水师', '巽为风', '风天小畜', '风火家人', '风雷益', '天雷无妄', '火雷噬嗑', '山雷颐', '山风蛊',
    '艮为山', '山火贲', '山天大畜', '山泽损', '火泽睽', '天泽履', '风泽中孚', '风山渐', '坤为地', '地雷复', '地泽临',
    '地天泰', '雷天大壮', '泽天夬', '水天需', '水地比', '离为火', '火山旅', '火风鼎', '火水未济', '山水蒙', '风水涣',
    '天水讼', '天火同人', '兑为泽', '泽水困', '泽地萃', '泽山咸', '水山蹇', '地山谦', '雷山小过', '雷泽归妹', '空白']
FULL_GUA_NAME = [
    '乾为天 (乾宫,六冲)', '天风姤 (乾宫)', '天山遁 (乾宫)', '天地否 (乾宫,六合)', '风地观 (乾宫)', '山地剥 (乾宫)',
    '火地晋 (乾宫,游魂)', '火天大有 (乾宫,归魂)', '震为雷 (震宫,六冲)', '雷地豫 (震宫,六合)', '雷水解 (震宫)',
    '雷风恒 (震宫)', '地风升 (震宫)', '水风井 (震宫)', '泽风大过 (震宫,游魂)', '泽雷随 (震宫,归魂)',
    '坎为水 (坎宫,六冲)', '水泽节 (坎宫,六合)', '水雷屯 (坎宫)', '水火既济 (坎宫)', '泽火革 (坎宫)', '雷火丰 (坎宫)',
    '地火明夷 (坎宫,游魂)', '地水师 (坎宫,归魂)', '巽为风 (巽宫,六冲)', '风天小畜 (巽宫)', '风火家人 (巽宫)',
    '风雷益 (巽宫)', '天雷无妄 (巽宫,六冲)', '火雷噬嗑 (巽宫)', '山雷颐 (巽宫,游魂)', '山风蛊 (巽宫,归魂)',
    '艮为山 (艮宫,六冲)', '山火贲 (艮宫,六合)', '山天大畜 (艮宫)', '山泽损 (艮宫)', '火泽睽 (艮宫)', '天泽履 (艮宫)',
    '风泽中孚 (艮宫,游魂)', '风山渐 (艮宫,归魂)', '坤为地 (坤宫,六冲)', '地雷复 (坤宫,六合)', '地泽临 (坤宫)',
    '地天泰 (坤宫,六合)', '雷天大壮 (坤宫,六冲)', '泽天夬 (坤宫)', '水天需 (坤宫,游魂)', '水地比 (坤宫,归魂)',
    '离为火 (离宫,六冲)', '火山旅 (离宫,六合)', '火风鼎 (离宫)', '火水未济 (离宫)', '山水蒙 (离宫)', '风水涣 (离宫)',
    '天水讼 (离宫,游魂)', '天火同人 (离宫,归魂)', '兑为泽 (兑宫,六冲)', '泽水困 (兑宫,六合)', '泽地萃 (兑宫)',
    '泽山咸 (兑宫)', '水山蹇 (兑宫)', '地山谦 (兑宫)', '雷山小过 (兑宫,游魂)', '雷泽归妹 (兑宫,归魂)']

# 每个卦宫 对应的物象
GUA_GONG_INFO = [
    "乾宫卦，乾为头|肺|大肠，为领导|老男人，为镜。",
    "震宫卦，震为足，为肝，肝藏魂藏血，为闹市。",
    "坎宫卦，坎为水，为耳|肾|膀胱，为尿|精|血，为偷盗|诈骗|作弊|风险，为江河|大海。",
    "巽宫卦，巽为花草，为编程|电脑|人工智能，为女人，为眼，为癌症。",
    "艮宫卦，艮为山，为鼻|乳房|脖子|肩膀，为坟墓。",
    "坤宫卦，坤为地，为柔软，为脾胃，为老妇人。",
    "离宫卦，离为火|光|激光|明亮|太阳，为文书|信息|文字|数据|图片|视频，为眼|血液|心脏，为小肠，为中暑。",
    "兑宫卦，兑为语言|口语|说话|声，为口腔|进食，为损坏，为20来岁少女，为咳嗽。"
]

# 用于建立 '硬币数组' 到 '卦序' 的一一对应关系
# gua_num: (六爻阳面硬币数，五爻，四爻，三爻，二爻，初爻)
GUA_NUM_TO_LIST = {
    0: (1, 1, 1, 1, 1, 1), 1: (1, 1, 1, 1, 1, 2), 2: (1, 1, 1, 1, 2, 2), 3: (1, 1, 1, 2, 2, 2),
    4: (1, 1, 2, 2, 2, 2), 5: (1, 2, 2, 2, 2, 2), 6: (1, 2, 1, 2, 2, 2), 7: (1, 2, 1, 1, 1, 1),
    8: (2, 2, 1, 2, 2, 1), 9: (2, 2, 1, 2, 2, 2), 10: (2, 2, 1, 2, 1, 2), 11: (2, 2, 1, 1, 1, 2),
    12: (2, 2, 2, 1, 1, 2), 13: (2, 1, 2, 1, 1, 2), 14: (2, 1, 1, 1, 1, 2), 15: (2, 1, 1, 2, 2, 1),
    16: (2, 1, 2, 2, 1, 2), 17: (2, 1, 2, 2, 1, 1), 18: (2, 1, 2, 2, 2, 1), 19: (2, 1, 2, 1, 2, 1),
    20: (2, 1, 1, 1, 2, 1), 21: (2, 2, 1, 1, 2, 1), 22: (2, 2, 2, 1, 2, 1), 23: (2, 2, 2, 2, 1, 2),
    24: (1, 1, 2, 1, 1, 2), 25: (1, 1, 2, 1, 1, 1), 26: (1, 1, 2, 1, 2, 1), 27: (1, 1, 2, 2, 2, 1),
    28: (1, 1, 1, 2, 2, 1), 29: (1, 2, 1, 2, 2, 1), 30: (1, 2, 2, 2, 2, 1), 31: (1, 2, 2, 1, 1, 2),
    32: (1, 2, 2, 1, 2, 2), 33: (1, 2, 2, 1, 2, 1), 34: (1, 2, 2, 1, 1, 1), 35: (1, 2, 2, 2, 1, 1),
    36: (1, 2, 1, 2, 1, 1), 37: (1, 1, 1, 2, 1, 1), 38: (1, 1, 2, 2, 1, 1), 39: (1, 1, 2, 1, 2, 2),
    40: (2, 2, 2, 2, 2, 2), 41: (2, 2, 2, 2, 2, 1), 42: (2, 2, 2, 2, 1, 1), 43: (2, 2, 2, 1, 1, 1),
    44: (2, 2, 1, 1, 1, 1), 45: (2, 1, 1, 1, 1, 1), 46: (2, 1, 2, 1, 1, 1), 47: (2, 1, 2, 2, 2, 2),
    48: (1, 2, 1, 1, 2, 1), 49: (1, 2, 1, 1, 2, 2), 50: (1, 2, 1, 1, 1, 2), 51: (1, 2, 1, 2, 1, 2),
    52: (1, 2, 2, 2, 1, 2), 53: (1, 1, 2, 2, 1, 2), 54: (1, 1, 1, 2, 1, 2), 55: (1, 1, 1, 1, 2, 1),
    56: (2, 1, 1, 2, 1, 1), 57: (2, 1, 1, 2, 1, 2), 58: (2, 1, 1, 2, 2, 2), 59: (2, 1, 1, 1, 2, 2),
    60: (2, 1, 2, 1, 2, 2), 61: (2, 2, 2, 1, 2, 2), 62: (2, 2, 1, 1, 2, 2), 63: (2, 2, 1, 2, 1, 1)}
HalfGua_TO_IDX = {
    (1, 1, 1): 0, (1, 1, 3): 1, (1, 3, 1): 2, (3, 1, 1): 3, (3, 3, 1): 4, (3, 1, 3): 5, (1, 3, 3): 6, (3, 3, 3): 7,
    (2, 1, 1): 8, (2, 1, 3): 9, (2, 3, 1): 10, (0, 1, 1): 11, (0, 3, 1): 12, (0, 1, 3): 13, (2, 3, 3): 14,
    (0, 3, 3): 15, (1, 2, 1): 16, (1, 2, 3): 17, (1, 0, 1): 18, (3, 2, 1): 19, (3, 0, 1): 20, (3, 2, 3): 21,
    (1, 0, 3): 22, (3, 0, 3): 23, (2, 2, 1): 24, (2, 2, 3): 25, (2, 0, 1): 26, (0, 2, 1): 27, (0, 0, 1): 28,
    (0, 2, 3): 29, (2, 0, 3): 30, (0, 0, 3): 31, (1, 1, 2): 32, (1, 1, 0): 33, (1, 3, 2): 34, (3, 1, 2): 35,
    (3, 3, 2): 36, (3, 1, 0): 37, (1, 3, 0): 38, (3, 3, 0): 39, (2, 1, 2): 40, (2, 1, 0): 41, (2, 3, 2): 42,
    (0, 1, 2): 43, (0, 3, 2): 44, (0, 1, 0): 45, (2, 3, 0): 46, (0, 3, 0): 47, (1, 2, 2): 48, (1, 2, 0): 49,
    (1, 0, 2): 50, (3, 2, 2): 51, (3, 0, 2): 52, (3, 2, 0): 53, (1, 0, 0): 54, (3, 0, 0): 55, (2, 2, 2): 56,
    (2, 2, 0): 57, (2, 0, 2): 58, (0, 2, 2): 59, (0, 0, 2): 60, (0, 2, 0): 61, (2, 0, 0): 62, (0, 0, 0): 63}
HalfGua_TO_NAME = {
    (1, 1, 1): '乾', (2, 1, 1): '兑', (1, 2, 1): '离', (2, 2, 1): '震', (1, 1, 2): '巽', (2, 1, 2): '坎',
    (1, 2, 2): '艮', (2, 2, 2): '坤', (1, 1, 3): '乾化巽', (1, 3, 1): '乾化离', (3, 1, 1): '乾化兑',
    (3, 3, 1): '乾化震', (3, 1, 3): '乾化坎', (1, 3, 3): '乾化艮', (3, 3, 3): '乾化坤', (2, 1, 3): '兑化坎',
    (2, 3, 1): '兑化震', (0, 1, 1): '兑化乾', (0, 3, 1): '兑化离', (0, 1, 3): '兑化巽', (2, 3, 3): '兑化坤',
    (0, 3, 3): '兑化艮', (1, 2, 3): '离化艮', (1, 0, 1): '离化乾', (3, 2, 1): '离化震', (3, 0, 1): '离化兑',
    (3, 2, 3): '离化坤', (1, 0, 3): '离化巽', (3, 0, 3): '离化坎', (2, 2, 3): '震化坤', (2, 0, 1): '震化兑',
    (0, 2, 1): '震化离', (0, 0, 1): '震化乾', (0, 2, 3): '震化艮', (2, 0, 3): '震化坎', (0, 0, 3): '震化巽',
    (1, 1, 0): '巽化乾', (1, 3, 2): '巽化艮', (3, 1, 2): '巽化坎', (3, 3, 2): '巽化坤', (3, 1, 0): '巽化兑',
    (1, 3, 0): '巽化离', (3, 3, 0): '巽化震', (2, 1, 0): '坎化兑', (2, 3, 2): '坎化坤', (0, 1, 2): '坎化巽',
    (0, 3, 2): '坎化艮', (0, 1, 0): '坎化乾', (2, 3, 0): '坎化震', (0, 3, 0): '坎化离', (1, 2, 0): '艮化离',
    (1, 0, 2): '艮化巽', (3, 2, 2): '艮化坤', (3, 0, 2): '艮化坎', (3, 2, 0): '艮化震', (1, 0, 0): '艮化乾',
    (3, 0, 0): '艮化兑', (2, 2, 0): '坤化震', (2, 0, 2): '坤化坎', (0, 2, 2): '坤化艮', (0, 0, 2): '坤化巽',
    (0, 2, 0): '坤化离', (2, 0, 0): '坤化兑', (0, 0, 0): '坤化乾'}

# 神煞对应表
gan_map = {
    '昼贵': ['巳', '丑', '子', '亥', '亥', '丑', '子', '丑', '午', '巳'],
    '夜贵': ['卯', '未', '申', '酉', '酉', '未', '申', '未', '寅', '卯'],
    '日德': ['巳', '寅', '申', '巳', '亥', ] * 2,
    '五合': ['巳', '未', '申', '戌', '亥', '丑', '寅', '辰', '巳', '未', ],
    '日禄': ['子', '寅', '卯', '巳', '午', '巳', '午', '申', '酉', '亥', ],
    '贤贵': [e for e in '午丑申寅寅'] * 2,
    '兼务': [e for e in '亥戌酉申未巳午辰卯寅'],
    '日解': [e for e in '酉亥申未丑'] * 2,
    '日医': [e for e in '巳卯亥丑未'] * 2,
    '阳刃': [e for e in '丑卯辰午未午未酉戌子'],
    '直符': [e for e in '戌巳辰卯寅丑午未申酉'],
    '游都': [e for e in '申丑子寅巳'] * 2,
    '鲁都': [e for e in '寅未午申亥'] * 2,
    '进神': ['子'] * 5 + ['卯'] * 5,
    '退神': ['丑'] * 5 + ['辰'] * 5,
    '进神*': ['午'] * 5 + ['酉'] * 5,
    '退神*': ['未'] * 5 + ['戌'] * 5,

}
date_map = {
    '日德': ["辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", ],
    # '日合': ['寅', '丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯'],
    # '日冲': ["巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰"],
    # '日刑': ["亥", "卯", "戌", "巳", "子", "辰", "申", "午", "丑", "寅", "酉", "未"],
    '驿马': ["巳", "寅", "亥", "申", ] * 3,
    '华盖': ['未', '辰', '丑', '戌'] * 3,
    '桃花': ['子', '酉', '午', '卯'] * 3,
    '亡神': ['寅', '亥', '申', '巳'] * 3,
    '雷电': ["卯", "辰", "辰", "未", "未", "戌", "戌", "丑", "丑", "寅", "寅", "卯", ],
    '日雨师': ["未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", ],
    '晴朗': ["巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", ],
    '将军': ["卯", "子", "酉", "午", ] * 3,

}
month_god_map = {
    # '月破': ["巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰"],
    # '月刑': ["亥", "卯", "戌", "巳", "子", "辰", "申", "午", "丑", "寅", "酉", "未"],
    # '月合': ['寅', '丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯'],

    '生气': ["酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申"],
    '死气': ["卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅"],
    '死神': ["寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"],
    '火烛': ["寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"],  # 同上

    '天医': ["未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午"],  # 有异议（卯午酉子*3）
    '地医': ["丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子"],
    '雨煞': ["酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", ],

    '天诏': ["申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", ],
    '飞魂': ["申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", ],  # 同上
    '月厌': ['丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯', '寅', ],
    '火光': ['丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯', '寅', ],  # 逆行12辰，同上
    # '风伯': ['亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯', '寅', '丑', '子', ],  # 逆行
    # '风煞': ['巳', '辰', '卯', '寅', '丑', '子', '亥', '戌', '酉', '申', '未', '午', ],  # 逆行
    '天烛': ['寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子', '丑'],
    '独火': ["午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳"],
    '天火': ['午', '卯', '子', '酉', '午', '卯', '子', '酉', '午', '卯', '子', '酉'],
    '霹雳': ['卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子', '丑', '寅'],
    '木狼': ['申', '寅', '申', '卯', '寅', '申', '丑', '戌', '辰', '子', '未', '戌'],
    '天河': ['丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子'],
    '退悔': ['戌', '戌', '戌', '未', '未', '未', '丑', '丑', '丑', '巳', '巳', '巳'],
    '成神': ["申", "亥", "寅", "巳"] * 3,
    '产煞': ["巳", "申", "亥", "寅"] * 3,
    '雷公': ["亥", "申", "巳", "寅", ] * 3,
    '雷煞': ["申", "巳", "寅", "亥", ] * 3,
    '会神': [e for e in '卯申辰未戌寅亥酉子丑午巳'],
    '天财': ["戌", "子", "寅", "辰", "午", "申", ] * 2,
    '天恩': ["丑", "卯", "巳", "未", "酉", "亥", ] * 2,
    '天马': ["子", "寅", "辰", "午", "申", "戌"] * 2,
    '解神': ["辰", "午", "午", "申", "申", "戌", "戌", "子", "子", "寅", "寅", "辰"],
    '活天赦': ["戌", "丑", "辰", "未"] * 3,
    '丧魄': ["辰", "丑", "戌", "未"] * 3,
    '咸池': ["子", "酉", "午", "卯"] * 3,
    '雨师': ["卯", "午", "酉", "子", ] * 3,
    '天鬼': ["午", "卯", "子", "酉"] * 3,
    '血支': ["丑", "申", "酉", "戌", "巳", "午", "未", "寅", "卯", "辰", "亥", "子", ],
    '血忌': ["亥", "午", "子", "丑", "未", "寅", "申", "卯", "酉", "辰", "戌", "巳"],
    '飞廉': ["戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉"],
    '天怪': ['辰', '卯', '寅', '丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', ],  # 逆行12辰

    # 季煞
    '天喜': ["未", "未", "未", "戌", "戌", "戌", "丑", "丑", "丑", "辰", "辰", "辰"],
    # '寡宿/关神': ["戌", "戌", "戌", "丑", "丑", "丑", "辰", "辰", "辰", "未", "未", "未", ],
    '浴盆': ["丑", "丑", "丑", "辰", "辰", "辰", "未", "未", "未", "戌", "戌", "戌", ],
    # '天目': ["丑", "丑", "丑", "辰", "辰", "辰", "未", "未", "未", "戌", "戌", "戌", ],
    # '皇书/战雄': ["亥", "亥", "亥", "寅", "寅", "寅", "巳", "巳", "巳", "申", "申", "申", ],
    '孤辰': ["寅", "寅", "寅", "巳", "巳", "巳", "申", "申", "申", "亥", "亥", "亥", ],
    '火鬼': ["卯", "卯", "卯", "午", "午", "午", "酉", "酉", "酉", "子", "子", "子", ],
    '丧车': ["午", "午", "午", "酉", "酉", "酉", "子", "子", "子", "卯", "卯", "卯"],
    '天赦': ["子", "子", "子", "寅", "寅", "寅", "午", "午", "午", "申", "申", "申"],
    '金神': ["酉", "巳", "丑"] * 4,

}
year_god_map = {
    '岁破': ["巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰"],
    '岁合': ['寅', '丑', '子', '亥', '戌', '酉', '申', '未', '午', '巳', '辰', '卯'],
    '岁刑': ["亥", "卯", "戌", "巳", "子", "辰", "申", "午", "丑", "寅", "酉", "未"],
    '劫煞': ["申", "巳", "寅", "亥", ] * 3,
    '灾煞': ['酉', '午', '卯', '子'] * 3,
    '岁煞': ["戌", "未", "辰", "丑"] * 3,

    '大煞': ["卯", "子", "酉", "午", ] * 3,
    '大将军': ['酉', '酉', '酉', '子', '子', '子', '卯', '卯', '卯', '午', '午', '午'],
    '破碎': ["酉", "巳", "丑"] * 4,
    '吊客': ["酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", ],  # 顺行
    '病符': ["戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", ],
    '丧门': ["丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", ],
    '年白虎': ["未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", ],

}
gua_god_map = {
    "卦身": ['巳', '午', '未', '申', '酉', '戌', '卯', '寅',
             '亥', '午', '丑', '寅', '酉', '辰', '卯', '申',
             '亥', '子', '未', '寅', '卯', '戌', '酉', '申',
             '巳', '子', '未', '申', '卯', '戌', '酉', '寅',
             '巳', '子', '丑', '申', '卯', '辰', '酉', '寅',
             '亥', '子', '丑', '寅', '卯', '辰', '酉', '申',
             '巳', '午', '丑', '申', '酉', '辰', '卯', '寅',
             '亥', '午', '未', '寅', '酉', '戌', '卯', '申'],
    "床帐": ['辰戌丑未', '辰戌丑未', '申酉', '亥子', '亥子', '申酉', '巳午',
             '巳午', '寅卯', '辰戌丑未', '申酉', '巳午', '亥子', '申酉', '巳午',
             '亥子', '寅卯', '寅卯', '申酉', '巳午', '巳午', '申酉', '亥子',
             '亥子', '辰戌丑未', '寅卯', '申酉', '亥子', '巳午', '申酉', '亥子',
             '巳午', '辰戌丑未', '寅卯', '申酉', '亥子', '巳午', '申酉', '亥子',
             '巳午', '寅卯', '寅卯', '申酉', '巳午', '巳午', '申酉', '亥子',
             '亥子', '辰戌丑未', '辰戌丑未', '申酉', '亥子', '亥子', '申酉', '巳午',
             '巳午', '寅卯', '辰戌丑未', '申酉', '巳午', '亥子', '申酉', '巳午', '亥子'],
    "香闺": ['申酉', '申酉', '亥子', '寅卯', '寅卯', '亥子', '辰戌丑未', '辰戌丑未', '巳午', '申酉', '亥子',
             '辰戌丑未', '寅卯', '亥子', '辰戌丑未', '寅卯', '巳午', '巳午', '亥子', '辰戌丑未', '辰戌丑未', '亥子',
             '寅卯', '寅卯', '申酉', '巳午', '亥子', '寅卯', '辰戌丑未', '亥子', '寅卯', '辰戌丑未', '申酉', '巳午',
             '亥子', '寅卯', '辰戌丑未', '亥子', '寅卯', '辰戌丑未', '巳午', '巳午', '亥子', '辰戌丑未', '辰戌丑未',
             '亥子', '寅卯', '寅卯', '申酉', '申酉', '亥子', '寅卯', '寅卯', '亥子', '辰戌丑未', '辰戌丑未', '巳午',
             '申酉', '亥子', '辰戌丑未', '寅卯', '亥子', '辰戌丑未', '寅卯']
}
# print('|'.join(list(year_god_map.keys())))
SHEN_SHA_STR = '日德|驿马|华盖|桃花|亡神|雷电|日雨师|晴朗|将军Date生气|死气|死神|火烛|天医|地医|雨煞|天诏|飞魂|月厌|火光|天烛|独火|天火' \
               '|霹雳|木狼|天河|退悔|成神|产煞|雷公|雷煞|会神|天财|天恩|天马|解神|活天赦|丧魄|咸池|雨师|天鬼|血支|血忌|飞廉|天怪|天喜|' \
               '浴盆|孤辰|火鬼|丧车|天赦|金神Month岁破|岁合|岁刑|劫煞|灾煞|岁煞|大煞|大将军|破碎|吊客|病符|丧门|年白虎Gua卦身|床帐|香闺'

# print(SHEN_SHA_STR.index('Date'),SHEN_SHA_STR.index('Month'),SHEN_SHA_STR.index('Gua'))
gua_num_dict = {
    '兄弟 持世': [6, 16, 19, 20, 24, 35, 38, 43, 48, 51, 53, 54, 59, 60],
    '子孙 持世': [5, 18, 28, 36, 37, 39, 40, 45, 46, 49, 52, 61],
    '妻财 持世': [3, 8, 9, 10, 12, 13, 15, 17, 23, 26, 27, 29, 30, 41, 57],
    '官鬼 持世': [2, 11, 22, 31, 32, 33, 34, 42, 47, 50, 55, 58, 62],
    '父母 持世': [0, 1, 4, 7, 14, 21, 25, 44, 56, 63],
    '兄弟 临应': [2, 19, 27, 29, 31, 33, 41, 51, 58],
    '子孙 临应': [9, 20, 22, 26, 32, 43, 50, 53, 55, 57],
    '妻财 临应': [8, 11, 12, 14, 15, 16, 25, 34, 42, 44, 46, 47, 49],
    '官鬼 临应': [1, 5, 7, 10, 18, 21, 24, 35, 37, 39, 40, 45, 48, 61],
    '父母 临应': [0, 3, 4, 6, 13, 17, 23, 28, 30, 36, 38, 52, 54, 56, 59, 60, 62, 63],
    '父母伏藏': [9, 10, 33, 34, 41, 43, 45, 46, 49, 50], '兄弟伏藏': [4, 5, 11, 12, 13, 14],
    '子孙伏藏': [2, 3, 4, 6, 12, 13, 14, 15, 30, 31, 33, 34, 35, 38, 62, 63],
    '妻财伏藏': [1, 2, 18, 19, 20, 22, 36, 37, 38, 39, 52, 53, 59, 60, 61, 62],
    '官鬼伏藏': [25, 26, 27, 30, 49, 51, 53, 54],
    '六爻 持世': [i * 8 for i in range(8)], '五爻 持世': [i * 8 + 5 for i in range(8)],
    '四爻 持世': [i * 8 + 1 for i in range(8)] + [i * 8 + 6 for i in range(8)],
    '三爻 持世': [i * 8 + 3 for i in range(8)] + [i * 8 + 7 for i in range(8)],
    '二爻 持世': [i * 8 + 2 for i in range(8)], '初爻 持世': [i * 8 + 1 for i in range(8)],
    '三爻 临应': [i * 8 for i in range(8)], '二爻 临应': [i * 8 + 5 for i in range(8)],
    '初爻 临应': [i * 8 + 1 for i in range(8)] + [i * 8 + 6 for i in range(8)],
    '六爻 临应': [i * 8 + 3 for i in range(8)] + [i * 8 + 7 for i in range(8)],
    '五爻 临应': [i * 8 + 2 for i in range(8)], '四爻 临应': [i * 8 + 1 for i in range(8)],
    '应爻 合妻财':[3, 9, 17, 41, 45, 53, 57, 63],
}

"""便捷排卦"""


class QuickPlace:
    def __init__(self, TimeList: list[int], Gua_nums, coins):
        # 需要什么用什么，自助；不用自己去算
        # coinsNumber_list是(六五四三二初)
        self.yearg, self.yearz, self.month, self.rigan, self.date, self.hour = TimeList
        self.gua_num, self.biangua_num = Gua_nums
        self.coinsNumber_list = [int(n) for n in coins]
        self.WuXing, self.SixMode = h_calculate(self.gua_num, self.rigan)

        self.trigger_li = [1 if r in [3, 0] else 0 for r in self.coinsNumber_list]

        self.self_posit, self.other_posit = search_self(self.gua_num)  # 爻位1-6

        self.GuaShu_li = gua_info_list_calculate(self.gua_num, self.biangua_num, self.trigger_li)
        # self.GuaShu_li：18位数组，顺序是Main，After，Hide

    '''general function'''

    def active_lst(self):
        # 输出词典的基本样式
        at_lst = []
        for i in range(12):
            # 遍历卦数的0-11 即主卦、变卦
            num = self.GuaShu_li[i]

            # 遍历到的数 变爻不能是None；主卦必须发动、暗动。两个条件满足其一。
            condition1 = i >= 6 and num is not None
            condition2 = self.trigger_li[i] == 1 or num == xiangchong(self.date) if i < 6 else False
            if condition1 or condition2:
                at_lst.append((i, num))  # 记录（爻位idx，60六亲数***）
        return at_lst

    def self_other_ps(self, skip=False):
        self_other_lst = [''] * 18
        self_other_lst[self.self_posit] = '世'
        self_other_lst[self.other_posit] = '应'
        if not skip:
            max_num = max(self.self_posit, self.other_posit)
            self_other_lst[max_num - 2], self_other_lst[max_num - 1] = '间', '间'
        return self_other_lst

    def DF_output(self):
        活跃列表 = self.active_lst()
        世应列表 = self.self_other_ps()
        六神列表 = Sixmode_to_Animals(self.SixMode)

        GuaImageDict = {'爻序': [], '爻位': [],
                        '六神': [],
                        '世应': [],
                        '六亲': [],
                        '支': [],
                        '五行': [],
                        '返卦': [],
                        '空亡': [],
                        '发动': [],
                        '月生': [],
                        '月合': [],
                        '月地': [], '月刑': [],
                        '日生': [],
                        '日合': [],
                        '日地': [], '日刑': [], '计数刑': [],
                        '60六亲': []
                        }
        for tuples in 活跃列表:
            idx = tuples[0]
            GuaImageDict[str(3 * idx)] = []  # 整除3，生克
            GuaImageDict[str(3 * idx + 1)] = []  # 除3余1，冲合值
            GuaImageDict[str(3 * idx + 2)] = []  # 除3余2，长生十二状态

        Month = LIU_QIN_NUM_60[self.WuXing][self.month % 12]
        Date = LIU_QIN_NUM_60[self.WuXing][self.date % 12]

        def yao_info(wx_int, zhi_int):
            Num = LIU_QIN_NUM_60[wx_int][zhi_int % 12]
            yao = FAMILY[Num]
            return [Num, yao[:2], yao[2], yao[3]]

        for i, num in enumerate(self.GuaShu_li):
            if num is not None:
                Num, lq_str, zhi_str, wx_str = yao_info(self.WuXing, num)
                是否空 = '空亡' if num in self.empty_lst else ''
                if i < 6:
                    if self.trigger_li[i] == 1:
                        是否动 = '发动'
                    elif num == xiangchong(self.date):
                        是否动 = '暗动'  # '暗动'
                    else:
                        是否动 = None
                elif i < 12:
                    是否动 = str(i % 6)  # ['发动']:str
                else:
                    是否动 = None

                li = [i, yao_wei[i % 6], 六神列表[i % 6], 世应列表[i], lq_str, zhi_str, wx_str, 返卦[num % 12], 是否空,
                      是否动,
                      生扶克(num, self.month % 12, '月破'), 冲合值(num, self.month), 长生_60[Month][lq_str],
                      刑(num, self.month),
                      生扶克(num, self.date), 冲合值(num, self.date), 长生_60[Date][lq_str], 刑(num, self.date),
                      计数刑(num, 活跃列表), Num]
                for m, n in zip(GuaImageDict.keys(), li):
                    GuaImageDict[m].append(n)  # 填表：对应的key，填充对应的value

                if 活跃列表:
                    for tuples in 活跃列表:
                        idx, value = tuples
                        Number = LIU_QIN_NUM_60[self.WuXing][value % 12]  # 60六亲的数
                        text = 生扶克(num, value, '变爻') if idx >= 6 else 生扶克(num, value)

                        GuaImageDict[str(3 * idx)].append(text)
                        GuaImageDict[str(3 * idx + 1)].append(冲合值(num, value))
                        GuaImageDict[str(3 * idx + 2)].append(长生_60[Number][lq_str])

        for (yao_xu, Num, name) in [(18, Month, '月建'), (19, Date, '日辰')]:
            yao = FAMILY[Num]
            dic = {'爻序': yao_xu, '六神': name, '六亲': yao[:2], '支': yao[2], '五行': yao[3], '返卦': 返卦[Num % 12],
                   '60六亲': Num, '月合': 冲合值(Num % 12, self.month), '月地': 长生_60[Month][yao[:2]], }
            for key, value in GuaImageDict.items():
                if key in dic:
                    GuaImageDict[key].append(dic[key])
                else:
                    GuaImageDict[key].append('')

        return GuaImageDict

    def 十二宫(self, load_csv=False):
        return [FAMILY[num] for num in LIU_QIN_NUM_60[self.WuXing]]

    def place(self, title, time):
        ric_gan_gap = self.date - self.rigan if self.rigan else self.date - 10  # 癸亥日，0-0，变成首位的“戌亥”
        empty = KONG_WANG[(ric_gan_gap + 12) % 12 // 2]
        text = '占题：' + title + '\n' + time + f'(空亡：{empty})'
        sign = ["×", '′', '″', "○"]
        main_lst, after_lst, hide_lst = [], [], []
        Family = self.十二宫()
        for rank, num in enumerate(self.GuaShu_li):
            string = Family[num % 12] if num else ''
            if rank < 6:
                main_lst.append(string)
            elif rank < 12:
                after_lst.append(string)
            else:
                hide_lst.append(string)
        if any(hide_lst):
            hide_lst = [n if n else ' ' * 8 for n in hide_lst]

        self_other = [n if n else ' ' * 2 for n in self.self_other_ps(skip=True)[:6]]
        six_animals = Sixmode_to_Animals(self.SixMode)

        condition = self.biangua_num != self.gua_num and self.biangua_num != 64
        headline = ' ' * 6 + FULL_GUA_NAME[self.biangua_num] if condition else ''
        text += '\n' + FULL_GUA_NAME[self.gua_num] + headline

        for i in range(6):
            n = self.coinsNumber_list[i]
            lst = [six_animals[i], hide_lst[i], main_lst[i] + sign[n], self_other[i],
                   after_lst[i] + sign[(n + 3) // 3] if after_lst[i] else '']
            line = ' '.join(lst)
            text += '\n' + line

        return text


def guaNum_to_CoinsNum(gua_num, bian_gua):
    if bian_gua == 64:
        return ''.join(str(e) for e in GUA_NUM_TO_LIST[gua_num])
    gua_list, biangua_list = GUA_NUM_TO_LIST[gua_num], GUA_NUM_TO_LIST[bian_gua]
    li = [str(g) if g == b else '3' if g == 1 else '0' for g, b in zip(gua_list, biangua_list)]
    return ''.join(li)


def h_calculate(gua_num: int=12, ri_gan: int=10):
    REMINDER_TO_WU_XING = [4, 3, 1, 3, 0, 0, 2, 4]
    REMAINDER_TO_SIX_MODE = [0, 1, 1, 2, 2, 3, 4, 5, 5, 0]
    return REMINDER_TO_WU_XING[gua_num // 8], REMAINDER_TO_SIX_MODE[ri_gan % 10]


def gua_info_list_calculate(gua_num: int, biangua_num: int, trigger_li: list[int]):
    def search_After():
        li = [None] * 6
        if biangua_num <= 63:  # 不是静卦的话
            Biangua_li = GUA_SHU[biangua_num]
            for i, n in enumerate(trigger_li):
                if n:
                    li[i] = Biangua_li[i]
        return li

    # 顺序是Main，After，Hide
    li = GUA_SHU[gua_num].copy()  # 直接赋值的话，li将会直接在gua_shu的内存上修改extend，影响下次赋值。
    li.extend(search_After())
    li.extend(HIDE_SHU[gua_num])  # GuaShu_li.extend(search_hide(self.gua_num))
    return li


def search_self(Guanum: int):
    '''
    给卦的序号，找出世应的idx
    :param Guanum:卦的序号
    :return: List[self_idx,other_idx]（5-0代表初爻到六爻）
    '''
    remain = Guanum % 8
    # idx_to_selfposit = [6, 1, 2, 3, 4, 5, 4, 3]原本是1-6代表初爻到六爻
    REMAINDER_SELF = [0, 5, 4, 3, 2, 1, 2, 3]  # 现在是5-0代表初爻到六爻，贴合gua_shu的习惯
    REMAINDER_OTHER = [3, 2, 1, 0, 5, 4, 5, 0]
    return [REMAINDER_SELF[remain], REMAINDER_OTHER[remain]]


def gua_information(gua_num, wuxing, SixMode) -> None:
    '''根据主卦序数，卦宫五行，天干模式，输出headline'''
    self_posit, _ = search_self(gua_num)
    self_zhi = GUA_SHU[gua_num][self_posit]
    liu_shen = Sixmode_to_Animals(SixMode)[self_posit]
    Num = LIU_QIN_NUM_60[wuxing][self_zhi % 12]

    print("【反馈】")
    text = f"世爻{FAMILY[Num]}在{YAO_WEI[self_posit]}爻临{liu_shen},{KEY_SAYING[liu_shen]}\n{GUA_GONG_INFO[gua_num // 8]}\n"
    for info_lst in GUA_INFO:
        text += f"{info_lst[gua_num]}"
    print(text)


# 确定今天的每个爻位轮值的六神： [六爻，五爻，...]
# Sixmode:0,壬癸日，1，甲乙日，2，丙丁日，3，戊日，4，己日，5，庚辛日
def Sixmode_to_Animals(Sixmode: int) -> list[str]:
    li = [ANIMALS[(Sixmode + 10 - i) % 6] for i in range(6)]
    return li


"""神煞部分"""


def find_shen_sha(date: int, month: int, gua_num: int = None, day_gan: int = None, yearz=None):
    """

    :param gua_num:卦序号
    :param day_gan:
    :param date:
    :param month:
    :param yearz:
    :return:
    """
    merged_dict = {}
    # ordered_dict = {zhi[i]: merged_dict.get(zhi[i]) for i in range(len(zhi))}

    text = ''

    merged_dict.update(append_dict(date % 4, date_map))
    # append_dict(day_gan % 10, h_god)
    merged_dict.update(append_dict(month % 12, month_god_map))
    # if gua_num:        merged_dict.update(append_dict(gua_num, gua_god_map))
    if yearz:
        append_dict(yearz % 12, year_god_map)

    ordered_dict = {key: merged_dict.get(key) for key in ZHI if key in merged_dict}

    for key, value in ordered_dict.items():
        text += f"{key} - {','.join(value)} ;\n"  # merged_dict.items()的内容填充text

    for key, value in gua_god_map.items():
        text += f"{key} - {gua_god_map[key][gua_num]};"

    return text


def append_dict(index, dict):
    """

    :param index:一般是给定的卦序号g，日辰ric及天干h，月令yuel，年yearz
    :param dict:
    :return:
    """
    merged_dict = {}
    for key, value in dict.items():
        if value[index] in merged_dict:
            merged_dict[value[index]].append(key)
        else:
            merged_dict[value[index]] = [key]

    return merged_dict


def find_shen_sha_(time_list: list, gua_num: int = None, as_text=False):
    def handle_time_list():
        # 天干地支字符转数字
        try:
            return [None if n is None else ZHI.index(n) if i % 3 else GAN.index(n) for i, n in enumerate(time_list)]
        except Exception as e:
            print(e, time_list)
            return []

    def add_shen_sha(idx: int, dic: dict):
        '''
        dic举例
        {'*昼贵*': ['卯', '丑', '子', '亥', '亥', '丑', '子', '丑', '寅', '卯'], '*夜贵*': ['巳', '未', '申', '酉', '酉', '未', '申', '未', '午', '巳']}
        '''
        for shen_sha_name, li in dic.items():
            # sha_zhi = ZHI.index(li[idx])
            sha_zhi = li[idx]
            for key in shen_sha_name.split('/'):
                if sha_zhi in merged_dict:
                    merged_dict[sha_zhi].append(key)
                else:
                    merged_dict[sha_zhi] = [key]

    merged_dict = {}
    if all(isinstance(n, int) or n is None for n in time_list):
        year_g, year_z, month, date_g, date_z, hour = time_list
    else:
        year_g, year_z, month, date_g, date_z, hour = handle_time_list()

    surface, hide = ('昼贵', '夜贵') if 4 <= date_g <= 9 else ('夜贵', '昼贵')  # 卯时开始用昼贵，酉时开始用夜贵
    # gui_ren = gan_map[surface][self.day_gan]
    # self.more_msg['幕帘'] = hide
    add_shen_sha(date_z, date_map)
    add_shen_sha(date_g, gan_map)
    if year_z is not None:
        add_shen_sha(year_z, year_god_map)
    if month is not None:
        add_shen_sha(month, month_god_map)
    if gua_num is not None:
        add_shen_sha(gua_num, gua_god_map)
    merged_dict[gan_map[hide][date_g]].append('幕帘')  # 添加神煞

    if as_text:
        return ''.join([f"{key} - {','.join(value)} ;\n" for key, value in merged_dict.items()])
    else:
        return merged_dict


"""提取干支时间信息"""


def findZodiacWord(search_string, kw, as_text=True, strict_mode=False):
    import re
    if strict_mode:
        pattern = f'(?P<year>(?P<gan>[甲乙丙丁戊己庚辛壬癸])(?P<zhi>[子丑寅卯辰巳午未申酉戌亥]){kw})'
    else:
        pattern = f'(?P<year>(?P<gan>[甲乙丙丁戊己庚辛壬癸])?(?P<zhi>[子丑寅卯辰巳午未申酉戌亥]){kw})'
    match = re.search(pattern, search_string)

    if match:
        gan = match.group('gan') if match.group('gan') else ''
        zhi = match.group('zhi')
        if as_text:
            return gan + zhi + kw
        else:
            return [GAN.index(gan) if gan else gan, ZHI.index(zhi) if zhi else zhi]
    else:
        return '' if as_text else [None, None]


def extract_time_from_text(text, args):
    # time_line = text.split('\n')[1] if '\n' in text else text
    time_line = text
    return [findZodiacWord(time_line, tag) for tag in args]


def extract_int_from_text(text):
    # time_line = text.split('\n')[1] if '\n' in text else text
    time_line = text
    _1, _2 = findZodiacWord(time_line, '年', False)
    _, _3 = findZodiacWord(time_line, '月', False)
    _4, _5 = findZodiacWord(time_line, '日', False, strict_mode=True)
    _, _6 = findZodiacWord(time_line, '时', False)
    return [_1, _2, _3, _4, _5, _6]


def save_to_db(db_path: str, json_path: str, start_from=None, exact_match=True):
    import sqlite3
    import json
    # 连接到数据库，创建游标对象
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS data (
                        title TEXT,
                        yuel TEXT,
                        h TEXT,
                        ric TEXT,
                        gua TEXT,
                        biangua TEXT,
                        coinsNumber_list TEXT,
                        content1 TEXT,
                        content2 TEXT,
                        content3 TEXT, 
                        gid INTEGER PRIMARY KEY AUTOINCREMENT
                    )''')

    # for message in message_list:
    file_name = json_path.split('/')[-1].split('.')[0]
    with open(json_path, 'r') as f:
        data = json.load(f)
    for message in pick_up_message(data, file_name, start_from, Exact_match=exact_match):
        if not message:
            continue
        # continue#测试时启用
        title, gua_image, text, note = message['title'], message['gua_image'], message['text'], message['note']
        _, _, month, date_g, date_z, _ = message['time_list']
        gua_num, bian_gua = message['gua']
        coins_num = message['coins_num']

        query = "INSERT INTO data (title, yuel, h, ric, gua, biangua, coinsNumber_list, content1, content2, content3) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
        cursor.execute(query, (
            title, ZHI[month % 12], GAN[date_g % 10], ZHI[date_z % 12], GUA_NAMES[gua_num],
            GUA_NAMES[bian_gua], coins_num, gua_image, text, note))

        print('保存成功：', title, month, date_g, date_z, gua_num, bian_gua)

    conn.commit()

    # 关闭游标和数据库连接
    cursor.close()
    conn.close()


"""文本识别 | 人性化"""

# HuaJia60 = [
#     "癸亥", "甲子", "乙丑", "丙寅", "丁卯", "戊辰", "己巳", "庚午", "辛未", "壬申", "癸酉", "甲戌",
#     "乙亥", "丙子", "丁丑", "戊寅", "己卯", "庚辰", "辛巳", "壬午", "癸未", "甲申", "乙酉", "丙戌",
#     "丁亥", "戊子", "己丑", "庚寅", "辛卯", "壬辰", "癸巳", "甲午", "乙未", "丙申", "丁酉", "戊戌",
#     "己亥", "庚子", "辛丑", "壬寅", "癸卯", "甲辰", "乙巳", "丙午", "丁未", "戊申", "己酉", "庚戌",
#     "辛亥", "壬子", "癸丑", "甲寅", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌",
# ]

HuaJia60 = [
    "甲子", "甲寅", "甲辰", "甲午", "甲申", "甲戌", "乙丑", "乙卯", "乙巳", "乙未", "乙酉", "乙亥",
    "丙子", "丙寅", "丙辰", "丙午", "丙申", "丙戌", "丁丑", "丁卯", "丁巳", "丁未", "丁酉", "丁亥",
    "戊子", "戊寅", "戊辰", "戊午", "戊申", "戊戌", "己丑", "己卯", "己巳", "己未", "己酉", "己亥",
    "庚子", "庚寅", "庚辰", "庚午", "庚申", "庚戌", "辛丑", "辛卯", "辛巳", "辛未", "辛酉", "辛亥",
    "壬子", "壬寅", "壬辰", "壬午", "壬申", "壬戌", "癸丑", "癸卯", "癸巳", "癸未", "癸酉", "癸亥"
]

"""
得:idx_1,之:idx_2
start_idx = text.find('得')
mid_idx = text.find('之')
mid_idx = mid_idx if 1 < mid_idx - start_idx < 10 else None

li = [(idx_1,gua_name_1),(idx_2,gua_name_2),(idx_3,gua_name_3),...]# gua_name_1是在text找到的字符，gua_idx_1是gua_name_1在text对应的索引
if len(li) >= 2 and start_idx != -1:
    1.筛选出 0 < idx - start_idx < 20的作为临时列表
    举例得字，在10个字符以内的。gua_idx_1 < idx_1
    是否存在“得”？离“得”字最近的，且在“得”之后不超过5个字符，作为主卦
    离“主卦”的idx不超过20个字符的，认为“变卦”

"""


# import chardet  # 【定位】多余
#
# def has_traditional_chinese(text):
#     result = chardet.detect(text.encode('utf-8'))
#     return result['language'] == 'zh-Hant'

def filter_indices(li, start_idx):
    # 筛选出满足条件的元素
    temp_list = [(idx, gua_name) for idx, gua_name in li if 0 < idx - start_idx < 20]
    return temp_list if temp_list else li


def find_2char_index(text, search_dic=None):
    # 检查是否有卦象的繁体字/模糊字。遍历字典，繁体替换为简体
    if search_dic is None:
        search_dic = GUA_NAME

    replace_map = {
        "離": "离", "濟": "济", "訟": "讼", "損": "损", "師": "师", "豐": "丰", "節": "节", "晉": "晋", "剝": "剥",
        "恆": "恒", "觀": "观", "過": "过", "隨": "随", "蟲": "蛊", "蠱": "蛊", "頤": "颐", "復": "复", "臨": "临",
        "賁": "贲", "無妄": "无妄", "謙": "谦", "渙": "涣", "漸": "渐", "歸": "归", "蓄": "畜", "遯": "遁",
        "為火": "为火", "大壯": "大壮", "為水": "为水", "為雷": "为雷", "兌為": "兑为", "為天": "为天", "為地": "为地",
        "為風": "为风", "為山": "为山", "風": "风", "澤": "泽", '曰': "日", "天风□": "天风姤", "天山□": "天山遁",
        "泽天□": "泽天夬", "水山赛": "水山蹇", "暌": "睽",
    }
    for old_word, new_word in replace_map.items():
        text = text.replace(old_word, new_word)

    # 遍历卦名g，在字符串s找到查找【卦名g】的【索引位置i】。(i,g)保存在列表s_idxes中。按照i排序，key=ele[0]

    # 只能找到出现一次的，出现两次以上的被忽略了。
    # s_idxes = [(s.find(g), g) for g in search_dic if s.find(g) != -1]

    # 能找到出现两次以上的：
    def find_all_occurrences(search_string, matching_name):
        s_idxes = []
        start_idx = 0

        # 死循环search字符串search_string所有的matching_name
        while True:

            # 指定了字符串s找字符g的起始索引：start_idx；找不到就退出循环
            idx = search_string.find(matching_name, start_idx)
            if idx == -1:
                break

            # 准备查找string的下一个matching_name，update起始索引start_idx
            start_idx = idx + len(matching_name)

            # 八卦名+宫的string不算进去；防止出现：乾宫/坎宫被算进去
            try:
                if search_string[start_idx] != "宫":
                    s_idxes.append((idx, matching_name))
            except IndexError:
                pass

        return s_idxes

    s_idxes = []
    for g in search_dic:
        s_idxes.extend(find_all_occurrences(text, g))

    s_idxes.sort(key=lambda x: x[0])

    start_idx = text.find('得')
    if start_idx != -1 and len(s_idxes) >= 2:
        s_idxes = filter_indices(s_idxes, start_idx)

    return s_idxes


def identify_GuaName(s, Exact_match=False, as_text=True, full_match=False):
    # GuaName_li[idx]为元组(s_idx,GuaName)

    # 能否的bug，识别出否卦来了
    s = s.replace("能否", "").replace("是否", "").replace("成否", "")
    s = s + '助'

    refer_lst = GUA_NAME
    if Exact_match:
        refer_lst = GUA_NAMES

    GuaName_li = find_2char_index(s, search_dic=refer_lst)

    find_out = []
    if (length := len(GuaName_li)) == 1:
        # 卦名GuaName_li[0][1]在 卦名列表guaname 中的序号
        find_out = [refer_lst.index(GuaName_li[0][1])]
    elif length == 2:
        find_out = list(map(lambda x: refer_lst.index(x), (GuaName_li[0][1], GuaName_li[1][
            1])))  # find_out = [refer_lst.index(GuaName_li[0][1]),refer_lst.index(GuaName_li[1][1])]

    elif length >= 3 and not full_match:
        # 找到相邻差距最小的两个数
        neibor_least_num = []
        mindiff = 100
        for i in range(len(GuaName_li) - 1):
            diff = GuaName_li[i + 1][0] - GuaName_li[i][0]
            if diff < mindiff:
                mindiff = diff
                neibor_least_num = [GuaName_li[i], GuaName_li[i + 1]]  # 此为元组
        find_out = list(map(lambda x: refer_lst.index(x), (neibor_least_num[0][1], neibor_least_num[1][1])))
    elif full_match:
        find_out = list(map(lambda x: refer_lst.index(x), [li[1] for li in GuaName_li]))
    if as_text:
        return ' '.join([str(n) for n in find_out])
    else:
        return find_out

    """
    引用方法：
    s = identify_60HuaJia(indentify_string)
    if s:
        self.input2.setText(s)
    """


def identify_60HuaJia(s: str):
    import re
    # 本来就是有日月格式的
    if "月" in s and "日" in s:

        # 识别诸如：1997年3月9日
        pattern = r"(\d{4})年(\d{1,2})月(\d{1,2})日"

        if matches := re.search(pattern, s):
            year = matches.group(1)
            month = matches.group(2)
            day = matches.group(3)
            from gettime import changed_time
            result_string = changed_time(year, month, day)

            return result_string

    string = ''
    huajia_li = find_2char_index(s, search_dic=HuaJia60)
    # 传入对应得到花甲在HuaJia60的索引 组成的列表
    if len(huajia_li) >= 4:
        time_li = ['年', '月', '日', '时']
        for i in range(4):
            string += huajia_li[i][1] + time_li[i]

    return string
    """
    引用方法：
    s = identify_60HuaJia(indentify_string)
    if s:
    # 识别不出来字体，就是空字符串；识别出来就整理好了
        self.input3.setText(s)
    """


def pick_up_message(text_dict, file_name: str, min_idx=None, Exact_match=True):
    for i, text in text_dict.items():
        tmp_dict = {}
        gua_params = identify_GuaName(text, Exact_match=Exact_match, as_text=False)
        time_info = ' '.join(e for e in extract_time_from_text(text, ['年', '月', '日', '时']) if e)
        if gua_params and '月' in time_info and '日' in time_info and (not min_idx or min_idx <= int(i)):
            tmp_dict['title'] = file_name + str(i)
            tmp_dict['note'] = file_name + str(i)
            tmp_dict['time_list'] = extract_int_from_text(text)

            if len(gua_params) == 1:
                gua_params += [64]
            elif gua_params[0] == gua_params[1]:
                gua_params[1] = 64
            tmp_dict['gua'] = gua_params
            tmp_dict['coins_num'] = guaNum_to_CoinsNum(gua_params[0], gua_params[1])

            model = QuickPlace(tmp_dict['time_list'], tmp_dict['gua'], tmp_dict['coins_num'])
            tmp_dict['gua_image'] = model.place(tmp_dict['title'], time_info)
            tmp_dict['text'] = text
        else:
            print('这个有问题：\n', gua_params, time_info, text[:50])
        yield tmp_dict


def check_json_text(json_path, Exact_match=True):
    import json
    with open(json_path, 'r') as f:
        data = json.load(f)
    for i, text in data.items():
        li = identify_GuaName(text, Exact_match=Exact_match, as_text=False, full_match=True)
        condition = False if len(li) == 4 and li[0] == li[2] and li[1] == li[3] else True

        # time_info = ' '.join(e for e in extract_time_from_text(text, ['年', '月', '日', '时']) if e)
        time_list = extract_int_from_text(text)
        time_condition = time_list[2] is None or time_list[3] is None or time_list[4] is None
        if len(li) >= 4 and condition and Exact_match:
            print(i, li)
        elif li == []:
            print(i, li, '没有找到卦名')
        elif not text.strip():
            print(i, '这是空文档')
        elif time_condition:
            print(i, '日月不全')

        # print([GUA_NAMES[e] for e in li])
    print('检查结束。')


if __name__ == '__main__':
    # print('/'.join([GUA_NAME[i * 8] + '变' for i in range(8)]))

    files = [
        'file/卦象集一.json', 'file/卦象集二.json', 'file/善三郎.json', 'file/疑惑指迷.json', 'file/说真.json',
        'file/自修宝典.json', 'file/占验技法.json', 'file/增删卜易.json', 'file/趋吉避凶.json', 'file/初学六爻.json',
        'file/误中悟.json', 'file/分科上.json', 'file/分科中.json', 'file/分科下.json', 'file/卦象解密.json', ]
    print(GUA_NAMES)
    # check_json_text('file/增删卜易.json',Exact_match=False)
    # input('下一步')
    # save_to_db('data/重中之重.db', 'file/增删卜易.json',exact_match=False)
    # save_to_db('data/case_storage.db', files[-1])
    # for path in files:
    #     print(path,":")
    #     condition = path!='file/增删卜易.json'
    #     check_json_text(path,Exact_match=condition)
    #     input('下一步')
    #     # save_to_db('data/重中之重.db', path,exact_match=False)
    #     save_to_db('data/case_storage.db', path,exact_match=condition)
    pass
